package services

import (
	"context"
	"math/big"

	"github.com/ethereum/go-ethereum"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
)

// GetBlockByNumber 通过区块高度查询区块
func (ec *EthClient) GetBlockByNumber(blockbuster *big.Int) (*types.Block, error) {
	block, err := ec.Client.BlockByNumber(context.Background(), blockbuster)
	if err != nil {
		return nil, err
	}
	return block, nil
}

// GetBlockByHash 通过区块哈希查询区块
func (ec *EthClient) GetBlockByHash(blockHash string) (*types.Block, error) {
	hash := common.HexToHash(blockHash)
	block, err := ec.Client.BlockByHash(context.Background(), hash)
	if err != nil {
		return nil, err
	}
	return block, nil
}

// GetBalance 查询余额
func (ec *EthClient) GetBalance(address string) (*big.Int, error) {
	ctx := context.Background()
	account := common.HexToAddress(address)
	balance, err := ec.Client.BalanceAt(ctx, account, nil)
	return balance, err
}

// GetTransaction 查询交易
func (ec *EthClient) GetTransaction(txHash string) (*types.Transaction, bool, error) {
	ctx := context.Background()
	hash := common.HexToHash(txHash)

	tx, isPending, err := ec.Client.TransactionByHash(ctx, hash)
	if err != nil {
		return nil, false, err
	}

	return tx, isPending, nil
}

// QueryContract 查询合约数据
func (ec *EthClient) QueryContract(contractAddress string, data []byte) ([]byte, error) {
	toAddr := common.HexToAddress(contractAddress)
	result, err := ec.Client.CallContract(context.Background(), ethereum.CallMsg{
		To:   &toAddr,
		Data: data,
	}, nil)
	if err != nil {
		return nil, err
	}
	return result, nil
}

// GetReceipt 查询收据
func (ec *EthClient) GetReceipt(txHash string) (*types.Receipt, error) {
	hash := common.HexToHash(txHash)
	receipt, err := ec.Client.TransactionReceipt(context.Background(), hash)
	if err != nil {
		return nil, err
	}
	return receipt, nil
}
